﻿/*
 * fixed_counter.hpp
 *
 *  Created on: 2020年7月21日
 *      Author: Dylan.Gao
 */

#ifndef _DM_FIXED_COUNTER_HPP_
#define _DM_FIXED_COUNTER_HPP_

namespace dm{

/**
 * 固定大小的计数器
 * T 计数器类型
 * Size 计数器大小
 */
template<typename T,T Size>
class TCFixedCounter{
public:
	TCFixedCounter( T c=0 ):m_c(c){}
	TCFixedCounter( const TCFixedCounter& c ):m_c(c.m_c){}

	static inline T size(){
		return Size;
	}

	inline void reset(){m_c=0;}

	inline const T& v()const{return m_c;}

	inline TCFixedCounter& operator=( T c ){m_c=c;return *this;}
	inline TCFixedCounter& operator=( const TCFixedCounter& c ){m_c=c.m_c;return *this;}

	inline bool operator==( const TCFixedCounter& c )const{ return m_c==c.m_c; }
	inline bool operator!=( const TCFixedCounter& c )const{ return m_c!=c.m_c; }

	inline bool operator==( T c )const{ return m_c==c; }
	inline bool operator!=( T c )const{ return m_c!=c; }

	inline TCFixedCounter& operator++(){
		++m_c;
		if( m_c==Size )
			m_c = 0;
		return *this;
	}

	inline TCFixedCounter& operator--(){
		if( m_c==0 )
			m_c = Size -1;
		else
			--m_c;
		return *this;
	}

	inline TCFixedCounter& operator+=( T c ){
		if( c>=Size )
			c %= Size;

		m_c += c;
		if( m_c>=Size )
			m_c -= Size;

		return *this;
	}

	inline TCFixedCounter& operator-=( T c ){
		if( c>=Size )
			c %= Size;

		if( m_c<c ){
			m_c += (Size-c);
		}else
			m_c -= c;

		return *this;
	}

	inline operator T()const{
		return m_c;
	}

	inline T operator-( const TCFixedCounter& c )const{
		if( m_c<c.m_c )
			return m_c+(Size-c.m_c);
		else
			return m_c - c.m_c;
	}

private:
	T m_c;	// 计数器
};

}

#endif /* INCLUDE_DM_FIXED_COUNTER_HPP_ */
